package com.lujieni.dbsharding.simple.aop;

import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
@Aspect
@Order(-1) // 如果一个方法被多个aop增强, 可以用@Order来控制增强顺序
public class ShardingTransactionAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShardingTransactionAspect.class);


    // 切点, 执行增强代码的地方
    @Pointcut("@annotation(org.apache.shardingsphere.transaction.annotation.ShardingTransactionType)")
    public void pointCut() {

    }

    //@Before 标识一个前置增强方法, 方法内部的增强代码叫做Advice切面或通知
    @Before("pointCut()")
    public void doBefore(JoinPoint point) {
        ShardingTransactionType ShardingTransaction = point.getTarget().getClass().getAnnotation(ShardingTransactionType.class);
        if (ShardingTransaction == null) {
            //注解在类上
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
            ShardingTransaction = method.getAnnotation(ShardingTransactionType.class);
        }
        TransactionTypeHolder.set(ShardingTransaction.value());
        LOGGER.info("选择Sharding分布式事务---" + ShardingTransaction.value().toString());
    }


    // @After 标识一个后置增强方法, 方法内部的增强代码叫做Advice切面或通知
    @After("pointCut()")
    public void doAfter() {
        TransactionTypeHolder.clear();
    }
}
